import os
import datetime
import time
import json
import paramiko
from astropy.io import fits
from threading import Timer


def getCurrentDayStr():
    current_utc = datetime.datetime.now(datetime.timezone.utc)
    current_date_str = current_utc.strftime('%y%m%d')
    return current_date_str

def getTodayStorePathBySearch(rootPath):

    todayStorePath = ""
    startObs = False

    templateFileName = "G005_054_241019"  
    templateFileNameLen = len(templateFileName)  
    templateFileNameSplitNum = len(templateFileName.split("_"))  
  
    dirPool = [rootPath]  
    curDateStr = getCurrentDayStr()

    for trootDir in dirPool:  
        if not os.path.exists(trootDir):  
            continue  
        obsDays = os.listdir(trootDir)  
        for obsDay in obsDays:
            if obsDay.find(curDateStr)>0 and len(obsDay) == templateFileNameLen and len(obsDay.split("_")) == templateFileNameSplitNum:  
                todayStorePath = "%s/%s"%(trootDir, obsDay)
                startObs = True
                break
        if startObs:
            break

    return startObs, todayStorePath

class TemperatureMonitor:
    def __init__(self, data_root, hostip_path):
        self.data_root = data_root
        self.hostip_path = hostip_path
        self.camera_list = self._load_camera_list()
        self.interval = 600  # 10分钟采集间隔(秒)
        self._start_monitoring()

    def _load_camera_list(self):
        """从hostip文件加载相机列表"""
        with open(self.hostip_path) as f:
            lines = f.readlines()
        #[f"G{int(line.strip()):03d}" for line in lines]
        return [f"{int(line.strip()):d}" for line in lines]

    def _start_monitoring(self):
        """启动定时监控"""
        self._monitor_temperatures()
        Timer(self.interval, self._start_monitoring).start()

    def _monitor_temperatures(self):
        """执行温度采集任务"""
        current_date = datetime.datetime.now(datetime.timezone.utc).strftime('%y%m%d')
        date_dir = os.path.join(self.data_root, current_date)
        os.makedirs(date_dir, exist_ok=True)

        for camera in self.camera_list:
            self._process_camera(camera, current_date)

    def _process_camera(self, camera, current_date):
        """处理单个相机的温度采集"""
        try:
            # 1. 连接到远程服务器
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ip = f"172.28.2.{camera}"
            ssh.connect(ip, username="gwac", password="gwac1234")
            
            # 2. 获取当天观测目录
            _, remote_path = self._get_remote_today_path(camera)
            if not remote_path:
                return
                
            # 3. 查找最新的FITS文件
            stdin, stdout, stderr = ssh.exec_command(f"ls -t {remote_path}/*.fit | head -1")
            latest_fit = stdout.read().decode().strip()
            
            if not latest_fit:
                return
                
            # 4. 检查文件是否已复制
            local_dir = os.path.join(self.data_root, current_date, camera)
            os.makedirs(local_dir, exist_ok=True)
            local_path = os.path.join(local_dir, os.path.basename(latest_fit))
            
            if os.path.exists(local_path):
                return
                
            # 5. 复制文件到本地
            sftp = ssh.open_sftp()
            sftp.get(latest_fit, local_path)
            sftp.close()
            
            # 6. 读取温度信息
            temps = self._read_temperature(local_path)
            
            # 7. 保存到JSON文件
            self._save_temperature_data(current_date, camera, temps)
            
        except Exception as e:
            print(f"处理相机{camera}时出错: {str(e)}")
        finally:
            if 'ssh' in locals():
                ssh.close()

    def _get_remote_today_path(self, camera):
        """获取远程服务器当天观测目录"""
        #/data/G006_064_250606
        
        # 直接使用当前UTC时间
        current_utc = datetime.datetime.now(datetime.timezone.utc)
        date_str = current_utc.strftime('%y%m%d')
            
        mountId = int(camera[:-1])
        cameraId = int(camera[-1])
        obs_dir = f"G{mountId:03d}_{mountId:02d}{cameraId}_{date_str}"
        
        tpath = f"/data/{obs_dir}"
        print(f"获取相机{camera}的远程路径: {tpath} (UTC时间: {current_utc})")
            
        return True, tpath

    def _read_temperature(self, fit_path):
        """从FITS文件读取温度信息"""
        with fits.open(fit_path) as hdul:
            # 根据文件扩展名选择正确的HDU
            if fit_path.endswith('.fit.fz'):
                header = hdul[1].header  # 对于.fit.fz文件使用第1个HDU
            else:
                header = hdul[0].header  # 对于.fit文件使用第0个HDU
                
            return {
                'tempset': float(header.get('TEMPSET', 0)),
                'tempact': float(header.get('TEMPACT', 0)),
                'dateobs': header.get('DATE-OBS', ''),
                'timeobs': header.get('TIME-OBS', '')
            }

    def _save_temperature_data(self, date, camera, temps):
        """保存温度数据到JSON文件"""
        json_path = os.path.join(self.data_root, date, f"{date}_temp.json")
        
        data = {}
        if os.path.exists(json_path):
            with open(json_path) as f:
                data = json.load(f)
                
        if camera not in data:
            data[camera] = []
            
        data[camera].append({
            'time': f"{temps['dateobs']} {temps['timeobs']}",
            'tempset': temps['tempset'],
            'tempact': temps['tempact']
        })
        
        with open(json_path, 'w') as f:
            json.dump(data, f, indent=2)

    def get_history_data(self):
        """获取历史数据列表"""
        history = []
        for date_dir in sorted(os.listdir(self.data_root), reverse=True):
            date_path = os.path.join(self.data_root, date_dir)
            if not os.path.isdir(date_path):
                continue
                
            json_path = os.path.join(date_path, f"{date_dir}_temp.json")
            if not os.path.exists(json_path):
                continue
                
            with open(json_path) as f:
                data = json.load(f)
                
            faulty_cameras = []
            for cam_id, entries in data.items():
                if any(abs(entry['tempset'] - entry['tempact']) > 5.0 for entry in entries):
                    faulty_cameras.append(cam_id)
            
            history.append({
                'date': date_dir,
                'total_cameras': len(data),
                'faulty_cameras': len(faulty_cameras),
                'faulty_list': faulty_cameras
            })
            
        return history

    def get_day_data(self, date):
        """获取某天的温度数据"""
        json_path = os.path.join(self.data_root, date, f"{date}_temp.json")
        if not os.path.exists(json_path):
            return []
            
        with open(json_path) as f:
            data = json.load(f)
            
        cameras = []
        for cam_name, entries in data.items():
            cameras.append({
                'name': cam_name,
                'times': [e['time'] for e in entries],
                'tempset': [e['tempset'] for e in entries],
                'tempact': [e['tempact'] for e in entries]
            })
            
        return cameras


if __name__ == "__main__":
    import time
    from getpass import getpass
    
    print("=== 温度监控测试程序 ===")
    print("将演示从远程服务器读取温度数据")
    
    # 初始化监控器
    monitor = TemperatureMonitor(
        data_root="/data/work/data/temp_monitor",
        hostip_path="/data/work/temp_monitor/hostip"
    )
    
    # 手动触发一次温度采集
    print("\n正在采集温度数据...")
    current_date = datetime.datetime.now(datetime.timezone.utc).strftime('%y%m%d')
    monitor._monitor_temperatures()
    
    # 显示采集结果
    print("\n采集完成！最新温度数据：")
    day_data = monitor.get_day_data(current_date)
    
    if not day_data:
        print("未获取到温度数据，请检查:")
        print("1. 远程服务器是否可访问")
        print("2. 当天是否有观测数据")
    else:
        for camera in day_data:
            last_temp = {
                'time': camera['times'][-1],
                'tempset': camera['tempset'][-1],
                'tempact': camera['tempact'][-1]
            }
            print(f"\n相机 {camera['name']}:")
            print(f"  最后记录时间: {last_temp['time']}")
            print(f"  设置温度: {last_temp['tempset']}°C")
            print(f"  实际温度: {last_temp['tempact']}°C")
            print(f"  温差: {abs(last_temp['tempset'] - last_temp['tempact']):.2f}°C")
